<Link>
该组件页面上渲染的就是一个<a>标签超链接,但行为却和传统的<a>不一样。
<Link to="/">home</Link>
//等价于
<Link to="/" children={"home"} />
//渲染在页面上
<a href="/">home</a>
正常情况下,点击a标签,页面发生跳转,这个时候浏览器是有刷新过程的。而<Link>渲染的a标签,会阻止这一默认行为,通过类似于this.props.history.push({})的方式添加历史栈,并指向目标路由。
to:string|object
当属性to的值为字符串时,就如上例那样,代表目标路由。
当值为一个对象时,通常包含如下属性:
<Link to={{
pathname:"/",
search:"?name=geralt",
hash:"#the-hash",
state:{loading:true}
}} >home</Link>
pathname就是路由,search为查询字符串,hash就是锚点hash。实际渲染在页面上就是这样的:
<a href="/?name=geralt#the-hash">home</a>
这里的关键点在state上,这里设置state的loading为true,并不是匹配路由"/"根组件state,也不是Link所属组件state,而是匹配路由根组件的props.location.state的loading为true,要特别注意这一点。
replace:bool
一个布尔值,当为true(或只添加属性没有值),表示在历史栈中,用该新的地址覆盖上一个旧地址 。
<Router>
<Link to="/a">a</Link>
<Link to="/b">b</Link>
<Link to="/c" replace={true}>c</Link>
<Link to="/d">d</Link>
</Router>
依次点击a、b、c、d,然后点后退,你以为是b、a吗?错啦,实际上是c、a。
c覆盖上一个历史栈,因为是b到c的,所以b的历史栈被c覆盖了,所以后退就是c、a。
<NavLink>
这是<Link>的特殊版本,to、replace属性用法与前者一致。
试想这么一种情况,我想让匹配当前路由的<Link>渲染的a有个底色,怎么做?
import React from 'react';
import ReactDOM from 'react-dom';
import {
BrowserRouter as Router,
Link,
Route
} from 'react-router-dom';
class MyComponent extends React.Component{
render(){
return(
<Router>
<div>
<Link to="/">Home</Link>
<Link to="/about">About</Link>
<Route path="/" component={()=>(<h1>Home</h1>)} />
<Route path="/about" component={()=>(<h1>About</h1>)} />
</div>
</Router>
);
}
}
ReactDOM.render(<MyComponent/>,document.querySelector("#root"));
如果这么写,MyComponent组件的render只有第一次渲染才会执行,切换路由的时候是不会触发该组件的任何生命周期函数,也就无法在该组件的生命周期函数内做操作。
有一种再次封装<Link>组件的方式可以实现,但等讲到Route组件的时候再说。现在<NavLink>就派上用场了。
activeClassName:string
当路由与该导航匹配,则添加该className,这个className可以是多个。
<Router>
<div>
<NavLink to="/" activeClassName="active">Home</NavLink>
<NavLink to="/about" activeClassName="active">About</NavLink>
<Route exact path="/" component={()=>(<h1>Home</h1>)} />
<Route exact path="/about" component={()=>(<h1>About</h1>)} />
</div>
</Router>
activeStyle:obj
当路由与该导航匹配,则添加样式。
<Router>
<div>
<NavLink to="/" activeStyle={{color:"red"}}>Home</NavLink>
<NavLink to="/about" activeStyle={{color:"red"}}>About</NavLink>
<Route exact path="/" component={()=>(<h1>Home</h1>)} />
<Route exact path="/about" component={()=>(<h1>About</h1>)} />
</div>
</Router>
如果你亲自写了,就会发现路由"/"总是有active的className、字体总是红色。这是因为对于"/about"这个路由,也是匹配"/"的。为了解决这个问题,可以设置exact属性和strict属性。
exact:bool
设置匹配模式是否为精确匹配。
<Router>
<div>
<NavLink exact to="/" activeClassName="active">Home</NavLink>
<NavLink exact to="/about" activeClassName="active">About</NavLink>
<Route exact path="/" component={()=>(<h1>Home</h1>)} />
<Route exact path="/about" component={()=>(<h1>About</h1>)} />
</div>
</Router>
这样,在访问"/about"路由的时候,"/"就不会也添加active的className了。
strict:bool
设置匹配模式是否为严格匹配。
对于"/about"和"/about/",如果不设置strict,会认为是相同的路由(虽然实际应用中的确是相同的)
<Router>
<div>
<NavLink exact strict to="/" activeClassName="active">Home</NavLink>
<NavLink exact strict to="/about" activeClassName="active">About</NavLink>
<Route exact path="/" component={()=>(<h1>Home</h1>)} />
<Route exact path="/about" component={()=>(<h1>About</h1>)} />
</div>
</Router>
一般这个属性相对用的较少,而exact用的很多。
isActive:func
当导航激活时触发该函数。
<Router>
<div>
<NavLink exact to="/" isActive={(match,location)=>{console.log(match,location)}}>Home</NavLink>
<NavLink exact to="/about" isActive={(match,location)=>{console.log(match,location)}}>About</NavLink>
<Route exact path="/" component={()=>(<h1>Home</h1>)} />
<Route exact path="/about" component={()=>(<h1>About</h1>)} />
</div>
</Router>
当设置了该属性,activeClassName和activeStyle就不会生效了。
该函数有2个参数,match和location,上述2个函数无论匹配哪个路由,都会触发,只是只有匹配成功的路由,match才会正确返回,否则返回null。对于match和location后边会专门介绍,这里就不讲了。
location:obj
这个属性是配合isActive用的,相当于重写isActive的第二个参数location,注意配置的location会影响第一个参数match。
<Router>
<div>
<NavLink exact to="/"
location={{pathname:"/"}}
isActive={(match,location)=>{console.log(match,location)}}
>Home</NavLink>
<NavLink exact to="/about"
location={{pathname:"/about"}}
isActive={(match,location)=>{console.log(match,location)}}
>About</NavLink>
<Route exact path="/" component={()=>(<h1>Home</h1>)} />
<Route exact path="/about" component={()=>(<h1>About</h1>)} />
</div>
</Router>
当设置了该属性,activeClassName和activeStyle就不会生效了。
对于上例,不管匹配那个路由,match都不是null而是一个完整的对象。其中配置了location的pathname是关键点,如果location没有pathname,那么match就是null了。